import java.util.*;

public class MyThread implements Runnable {

    private static final String lock = "lock";

    private static  Queue<StringPair> QUEUE_TIMES = new LinkedList<StringPair>();

    public static int activeCount = 5;

    private String name;

    public MyThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        while (QUEUE_TIMES.size() > 0 && activeCount > 0) {

            StringPair stringPair = nextPair();
            System.out.println("Thread"+name+"获取到了pid：" + stringPair.getPid());
            if (!spider(stringPair.getPid())) {
                checkTimes(stringPair);
                continue;
            }
            System.out.println("Thread"+name+"爬取pid="+stringPair.getPid()+"成功");
        }
    }

    private synchronized StringPair nextPair() {

        if(QUEUE_TIMES.size() == 0) {
            try {
                System.out.println("阻塞线程"+name);
                QUEUE_TIMES.wait();
                activeCount--;
                System.out.println("当前活动线程数："+activeCount);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return QUEUE_TIMES.poll();
    }

    private synchronized void checkTimes(StringPair stringPair) {
        int times = stringPair.getTimes();
        if (times >= 2) {
            System.out.println(stringPair.getPid() + "题已爬取失败了2次，不再放入队列");
            return;
        }

        stringPair.setTimes(times + 1);
        QUEUE_TIMES.offer(stringPair);
        if(activeCount < 5){
            System.out.println("唤醒线程");
            QUEUE_TIMES.notify();
            activeCount++;
            System.out.println("当前活动线程数："+activeCount);
        }
        return;
    }

    private boolean spider(int pid) {

        System.out.println("Thread-" + name + ":开始爬取pid=" + pid);
        try {
            Thread.sleep(3 * 1000);
            if (pid % 3 == 0) {
                throw new Exception("Thread"+name+"爬取"+pid+"出错");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();

            return false;
        } catch (Exception ex) {

            ex.printStackTrace();
            System.out.println("Thread-" + name + ":爬取pid=" + pid + "出错");

            if(1017 == pid){
                try {
                    Thread.sleep(20 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return false;
        }

        return true;
    }

    public static void init(int maxPid) {
        for (int i = 1000; i < maxPid; i++) {
            StringPair stringPair = new StringPair();
            stringPair.setPid(i);
            stringPair.setTimes(0);
            QUEUE_TIMES.offer(stringPair);
        }
        System.out.printf("初始化完成.......");
    }
}
